home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’92 / DylanTalk / DylanTalk Source / Personality.c < prev    next >
Encoding:
Text File  |  1992-06-14  |  9.1 KB  |  289 lines  |  [TEXT/MPS ]

  1. // DylanTalk by Dean Yu & Fred Monroe (CEO & Chief Technology Officer)
  2. //
  3. //    © 1992 FGM Enterprises.  All rights reserved.
  4. //
  5. //    Personality.c – Code that handles preferences and switching personality files
  6. //
  7.  
  8. #include <Types.h>
  9. #include <Errors.h>
  10. #include <Files.h>
  11. #include <Folders.h>
  12. #include <Fonts.h>
  13. #include <GestaltEqu.h>
  14. #include <Layers.h>
  15. #include <Menus.h>
  16. #include <OSUtils.h>
  17. #include <Resources.h>
  18. #include <SysEqu.h>
  19. #include <ToolUtils.h>
  20. #include <Windows.h>
  21.  
  22. #include <DylanTalk.h>
  23.  
  24. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  25. // Routine to open the preferred personality file, or the default one if the preferred
  26. // one isn’t there.  Also creates the preferences file & folder if they don’t exist.
  27. pascal void    OpenPersonalityFile(void)
  28. {
  29.     OSErr                    err;
  30.     short                    prefsVRefNum;
  31.     short                    prefsRefNum;
  32.     short                    personalityRefNum;
  33.     long                    prefsDirID;
  34.     DylanTalkGlobalHandle    globals;
  35.     StringHandle            prefsInfo;
  36.     CInfoPBRec                catInfo;
  37.     HParamBlockRec            folderInfo;
  38.     
  39.     Gestalt(gestaltDylanTalk, &((long) globals));
  40.     if (FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, &prefsVRefNum, &prefsDirID) == noErr) {
  41.         prefsInfo = GetResource('STR ', rDylanTalkPreferencesFile);
  42.         DetachResource(prefsInfo);
  43.         (**globals).preferencesFileName = prefsInfo;
  44.         
  45.         // See if our preferences folder is there.
  46.         
  47.         catInfo.dirInfo.ioNamePtr = *prefsInfo;
  48.         catInfo.dirInfo.ioVRefNum = prefsVRefNum;
  49.         catInfo.dirInfo.ioFDirIndex = 0;
  50.         catInfo.dirInfo.ioDrDirID = prefsDirID;
  51.         err = PBGetCatInfoSync(&catInfo);
  52.         
  53.         // If it’s not, create it.
  54.         
  55.         if (err == fnfErr) {
  56.             folderInfo.fileParam.ioNamePtr = *prefsInfo;
  57.             folderInfo.fileParam.ioVRefNum = prefsVRefNum;
  58.             folderInfo.fileParam.ioDirID = prefsDirID;
  59.             err = PBDirCreateSync(&folderInfo);                            // Create DylanTalk Preferences folder
  60.             if (err == noErr)
  61.                 prefsDirID = folderInfo.fileParam.ioDirID;
  62.         }
  63.         else
  64.             prefsDirID = catInfo.dirInfo.ioDrDirID;
  65.         
  66.         // Save the directory in our globals
  67.         
  68.         (**globals).preferencesVRefNum = prefsVRefNum;
  69.         (**globals).preferencesDirID = prefsDirID;
  70.  
  71.         // Try to create the preferences file inside the folder.  (If it already exists, we’ll just get an error back.
  72.         
  73.         HCreateResFile(prefsVRefNum, prefsDirID, *prefsInfo);
  74.         prefsRefNum = HOpenResFile(prefsVRefNum, prefsDirID, *prefsInfo, fsCurPerm);    // Open the preferences file.
  75.  
  76.         prefsInfo = Get1Resource('STR ', rPreferredPersonality);        // Get the preferred personality file
  77.         if (prefsInfo == nil) {
  78.             prefsInfo = GetResource('STR ', rDefaultPersonality);        // Get the default one if there is no preferred one.
  79.             DetachResource((Handle) prefsInfo);                            // Detach the default string
  80.             AddResource((Handle) prefsInfo, 'STR ', rPreferredPersonality, "\p");    // And use it as the preferred personality.
  81.             WriteResource((Handle) prefsInfo);
  82.         }
  83.         
  84.         // Now open the personality file
  85.         
  86.         personalityRefNum = SwitchPersonalityFile(*prefsInfo);            // Switch to it.
  87.         
  88.         // Save the personality file in our globals
  89.         
  90.         (**globals).personalityFile = personalityRefNum;
  91.         
  92.         // Close the preferences file
  93.         
  94.         CloseResFile(prefsRefNum);
  95.     }
  96. }
  97.  
  98. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  99. // ChooseNewPersonality – Close the current personality file, and open the one
  100. // that the user just picked from the menu
  101. pascal void ChooseNewPersonality(short itemNumber, MenuHandle personalityMenu)
  102. {
  103.     short                    currentMark;
  104.     short                    newPersonalityFile;
  105.     short                    prefsRefNum;
  106.     DylanTalkGlobalHandle    globals;
  107.     Handle                    oldPersonality;
  108.     Str255                    newPersonality;
  109.     
  110.     // If the user picked the current personality, don’t bother doing anything
  111.     
  112.     GetItemMark(personalityMenu, itemNumber, ¤tMark);
  113.     if (currentMark != checkMark) {
  114.         Gestalt(gestaltDylanTalk,&((long) globals));
  115.         
  116.         // Switch personality files
  117.         
  118.         GetItem(personalityMenu, itemNumber, &newPersonality);
  119.         newPersonalityFile = SwitchPersonalityFile(newPersonality);
  120.         (**globals).personalityFile = newPersonalityFile;
  121.         
  122.         // Uncheck the old personality, and check the new one
  123.         
  124.         CheckItem(personalityMenu, (**globals).personalityItem, false);
  125.         CheckItem(personalityMenu, itemNumber, true);
  126.         (**globals).personalityItem = itemNumber;
  127.         
  128.         // Write the new personality out to the preferences file
  129.         
  130.         prefsRefNum = HOpenResFile((**globals).preferencesVRefNum, (**globals).preferencesDirID,
  131.                                     *((**globals).preferencesFileName), fsCurPerm);
  132.         oldPersonality = Get1Resource('STR ', rPreferredPersonality);
  133.         if (oldPersonality == nil) {
  134.             oldPersonality = (Handle) NewString(newPersonality);
  135.             AddResource(oldPersonality, 'STR ', rPreferredPersonality, "\p");
  136.         }
  137.         else {
  138.             PtrToXHand(newPersonality, oldPersonality, (long) (newPersonality[0] + 1));
  139.             ChangedResource(oldPersonality);
  140.         }
  141.         WriteResource(oldPersonality);
  142.         CloseResFile(prefsRefNum);
  143.     }
  144. }
  145.  
  146. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  147. pascal short SwitchPersonalityFile(Str255 personalityFile)
  148. {
  149.     short                     refNum;
  150.     short                    resRef;
  151.     short                    prefsVRefNum;
  152.     long                    prefsDirID;
  153.     res_map_handle            map_copy;
  154.     res_map_handle            curr_map;
  155.     DylanTalkGlobalHandle    globals;
  156.     
  157.     // Get our globals
  158.     
  159.     Gestalt(gestaltDylanTalk, &((long) globals));
  160.     prefsDirID = (**globals).preferencesDirID;
  161.     prefsVRefNum = (**globals).preferencesVRefNum;
  162.     
  163.     // Close the current personality file if one is open
  164.     
  165.     if ((refNum = (**globals).personalityFile) > 0)
  166.         CloseResFile(refNum);
  167.         
  168.     // Open up the new one.
  169.         
  170.     refNum = HOpenResFile(prefsVRefNum, prefsDirID, personalityFile, fsCurPerm);
  171.     if (!ResError())
  172.     {
  173.         map_copy = *(res_map_handle *)TopMapHndl;                // Get handle to Personality resource map
  174.     
  175.         curr_map = (*map_copy)->next_map;                        // Get the map underneath the Personality file
  176.         resRef = (*curr_map)->refNum;                            // And it’s file reference number
  177.         
  178.         *((res_map_handle *)TopMapHndl) = curr_map;                // Make that map the top and current map
  179.         *((short *)CurMap) = resRef;
  180.         
  181.         (*map_copy)->next_map = nil;                            // Put Personality file at the bottom of the resource chain
  182.         while ((*curr_map)->next_map != nil)                    // Look for the current bottom of the chain
  183.             curr_map = (*curr_map)->next_map;
  184.         (*curr_map)->next_map = map_copy;                        // And tack the Personality file after that.
  185.     }
  186.     else
  187.         refNum = 0;
  188.         
  189.     return refNum;
  190. }
  191.  
  192. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  193. // Routine to look for personality files in the Preferences folder, and put each
  194. // one it finds in the personality menu.
  195.  
  196. pascal void FillPersonalityMenu(MenuHandle personalityMenu)
  197. {
  198.     short        fileIndex; 
  199.     short        personalityCount;
  200.     short        prefsVRefNum;
  201.     OSErr        err;
  202.     long        prefsDirID;
  203.     Str255        prefsFileName;
  204.     CInfoPBRec    catInfo;
  205.     DylanTalkGlobalHandle    globals;
  206.     
  207.     // Install the about item and a line at the top of the menu
  208.     
  209.     AppendMenu(personalityMenu, "\pAbout DylanTalk…");
  210.     AppendMenu(personalityMenu, "\p(-");
  211.     
  212.     // Get our DylanTalk globals
  213.     
  214.     Gestalt(gestaltDylanTalk, &((long) globals));
  215.     prefsDirID = (**globals).preferencesDirID;
  216.     prefsVRefNum = (**globals).preferencesVRefNum;
  217.     
  218.     // If our About Box window didn’t load, or Times 72 isn’t availabe, disable
  219.     // the About Box item.
  220.     
  221.     if ((**globals).aboutPicture == nil)
  222.         DisableItem(personalityMenu, 1);
  223.         
  224.     fileIndex = 1;
  225.     personalityCount = 3;
  226.     
  227.     // Set up some stuff for GetCatInfo
  228.     
  229.     catInfo.hFileInfo.ioCompletion = nil;
  230.     catInfo.hFileInfo.ioNamePtr = prefsFileName;
  231.     catInfo.hFileInfo.ioVRefNum = prefsVRefNum;
  232.     
  233.     do {
  234.         catInfo.hFileInfo.ioFDirIndex = fileIndex++;
  235.         catInfo.hFileInfo.ioDirID = prefsDirID;
  236.         err = PBGetCatInfoSync(&catInfo);                    // Get file information
  237.         
  238.     // If this file is a Personality file, add it to the Personality menu
  239.     
  240.         if (err == noErr &&
  241.             ((catInfo.hFileInfo.ioFlFndrInfo.fdType == kDylanTalkPersonalityFileType) &&
  242.             (catInfo.hFileInfo.ioFlFndrInfo.fdCreator == kDylanTalkCreator))) {
  243.                 AppendMenu(personalityMenu, "\p ");
  244.                 SetItem(personalityMenu, personalityCount++, prefsFileName);
  245.                 
  246.                 // Check the current personality.
  247.                 
  248.                 if (catInfo.hFileInfo.ioFRefNum == (**globals).personalityFile) {
  249.                     CheckItem(personalityMenu, personalityCount - 1, true);
  250.                     (**globals).personalityItem = personalityCount - 1;
  251.                 }
  252.         }
  253.     } while (err == noErr);
  254. }
  255.  
  256. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  257. // DylanTalk About Box
  258.  
  259. pascal void DylanTalkAbout(void)
  260. {
  261.     DylanTalkGlobalHandle    globals;
  262.     WindowPtr                aboutBox;
  263.     PicHandle                aboutBoxPicture;
  264.     GrafPtr                    oldPort;
  265.     Rect                    boundsRect;
  266.     WindowRecord            aboutBoxStorage;
  267.     
  268.     Gestalt(gestaltDylanTalk, &((long) globals));            // Get our globals
  269.     aboutBoxPicture = (**globals).aboutPicture;
  270.     
  271.     SetRect(&boundsRect, ((**aboutBoxPicture).picFrame).left, ((**aboutBoxPicture).picFrame).top,
  272.                         ((**aboutBoxPicture).picFrame).right, ((**aboutBoxPicture).picFrame).bottom);
  273.     aboutBox = NewWindow(&aboutBoxStorage, &boundsRect, "\p", false, altDBoxProc, (WindowPtr) -1, false, 0);
  274.     AutoPositionWindow(aboutBox, lcMainScreen, hcCenter, vcAlertCenter);
  275.  
  276.     ShowWindow(aboutBox);                                    // Show it.
  277.     GetPort(&oldPort);
  278.     SetPort(aboutBox);
  279.     DrawPicture(aboutBoxPicture, &boundsRect);
  280.     SetPort(oldPort);
  281.     
  282.     // Wait for the user to click the mouse
  283.     
  284.     do {
  285.     } while (Button() == false);
  286.     
  287.     CloseWindow(aboutBox);
  288. }
  289.